﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using Microsoft.Win32;
using ObservadorPeplau.API.Business;
using System.Runtime.Serialization.Formatters.Binary;

namespace ObservadorPeplau.API.DAL
{
    /// <summary>
    /// Saves and retrieves Discussions from registry using the following structure:
    /// 
    /// DiscussionRepository
    ///     - Url1 (serialized object)
    ///     - Url2 ...
    /// Marked
    ///     - Stared (boolean pairs 'Url'=>true/false)
    ///     - Read
    ///     - ...
    /// 
    /// </summary>
    internal class DiscussionRegistryDAO
    {
        public bool IsMarked(string valueKey, string mark)
        {
            var markedKey = GetOrCreateMarkedTypeKey(mark);
            return bool.Parse(markedKey.GetValue(valueKey, "False").ToString());
        }

        public void SetMarked(string valueKey, string mark, bool isMarked)
        {
            if (isMarked)
            {
                GetOrCreateMarkedTypeKey(mark).SetValue(valueKey, true);
            }
            else
            {
                if (GetOrCreateMarkedTypeKey(mark).GetValue(valueKey) != null)
                    GetOrCreateMarkedTypeKey(mark).DeleteValue(valueKey);
            }
        }

        internal List<Discussion> GetMarked(string mark)
        {
            var discussionMarkedTypeKey = GetOrCreateMarkedTypeKey(mark);
            return discussionMarkedTypeKey.GetValueNames().Select(GetDiscussionFromRepository).ToList();
        }

        public Discussion GetDiscussionFromRepository(string url)
        {
            var savedDiscussionKey = GetOrCreateDiscussionRepository().OpenSubKey(url);
            if (savedDiscussionKey == null)
                return null;

            var savedDiscussionXml = savedDiscussionKey.GetValue(Constants.DefaultValueName).ToString();
            var savedDiscussionObject = (Discussion)SerializationManager.DeserializeFromXml(savedDiscussionXml, typeof(Discussion));
            return savedDiscussionObject;
        }


        internal void ClearMark(string mark)
        {
            var discussionMarkedTypeKey = GetOrCreateMarkedTypeKey(mark);
            discussionMarkedTypeKey.GetValueNames().ToList().ForEach(discussionMarkedTypeKey.DeleteValue);
        }

        internal void SaveDiscussionOnRegistry(Discussion discussion)
        {
            var serialized = SerializationManager.SerializeToXml(discussion);

            var discussionKey = RegistryManager.GetOrCreateRegistryKey(discussion.Url, GetOrCreateDiscussionRepository());
            discussionKey.SetValue(Constants.DefaultValueName, serialized);
        }

        private RegistryKey GetOrCreateDiscussionRepository()
        {
            return RegistryManager.GetOrCreateRegistryKey(Constants.DiscussionRepositoryKey);
        }

        private RegistryKey GetOrCreateMarkedTypeKey(string markedType)
        {
            return RegistryManager.GetOrCreateRegistryKey(markedType, RegistryManager.GetOrCreateRegistryKey(Constants.DiscussionMarkedKey));
        }
    }
}
